use crate::git::commands::RepositoryStatus;
use anyhow::Result;
use git2::{Repository, StatusOptions};
use tokio::task;

/// 获取工作区状态
pub async fn get_working_dir_status() -> Result<RepositoryStatus> {
    task::spawn_blocking(|| {
        let repo = Repository::open(".")?;
        let mut status_options = StatusOptions::new();
        status_options
            .include_untracked(true)
            .recurse_untracked_dirs(true);

        let statuses = repo.statuses(Some(&mut status_options))?;

        // 使用 RepositoryStatus 而不是 WorkingDirStatus
        let mut status = RepositoryStatus {
            untracked: Vec::new(),
            modified: Vec::new(),
            staged: Vec::new(),
            conflicted: Vec::new(),
        };

        for entry in statuses.iter() {
            let path = match entry.path() {
                Some(p) => p.to_string(),
                None => continue,
            };

            let status_flags = entry.status();

            if status_flags.is_wt_new() {
                status.untracked.push(path.clone());
            } else if status_flags.is_wt_modified() {
                status.modified.push(path.clone());
            } else if status_flags.is_wt_deleted()
                || status_flags.is_wt_renamed()
                || status_flags.is_wt_typechange()
            {
                status.modified.push(path.clone());
            }

            if status_flags.is_index_new()
                || status_flags.is_index_modified()
                || status_flags.is_index_deleted()
                || status_flags.is_index_renamed()
                || status_flags.is_index_typechange()
            {
                status.staged.push(path.clone());
            }

            if status_flags.is_conflicted() {
                status.conflicted.push(path.clone());
            }
        }

        Ok(status)
    })
    .await?
}

/// 获取某个文件的diff
pub async fn get_file_diff(file_path: &str) -> Result<String> {
    let file_path = file_path.to_string();

    task::spawn_blocking(move || {
        let repo = Repository::open(".")?;
        let mut opts = git2::DiffOptions::new();
        opts.pathspec(file_path.clone());

        // 获取文件的diff
        let diff = repo.diff_index_to_workdir(None, Some(&mut opts))?;

        // 将diff转换为字符串
        let mut diff_str = String::new();
        diff.print(git2::DiffFormat::Patch, |_delta, _hunk, line| {
            match line.origin() {
                '+' | '-' | ' ' => {
                    diff_str.push(line.origin());
                    diff_str.push_str(std::str::from_utf8(line.content()).unwrap_or(""));
                }
                _ => {}
            }
            true
        })?;

        Ok(diff_str)
    })
    .await?
}
